package iscas;

import redis.clients.jedis.Jedis;

abstract class RedisLocalState {
    String name, lock;
    volatile boolean closed = false;

    public RedisLocalState(String name, long period) {
        this.name = name;
        this.lock = name + "_lock";
        periodicMerge(period);
    }

    public abstract void merge(Jedis jedis);

    void lock(Jedis jedis) {
        while (jedis.setnx(lock, "1") != 1) {
            try {
                // noinspection BusyWait
                Thread.sleep(500);
            } catch (InterruptedException ignored) {
            }
        }
    }

    void unlock(Jedis jedis) {
        jedis.del(lock);
    }

    abstract boolean isEmpty();

    protected void periodicMerge(long period) {
        new Thread(() -> {
            Jedis jedis = RedisConfig.newJedis();
            while (true) {
                if (!isEmpty()) {
                    merge(jedis);
                }
                if (closed) {
                    break;
                }
                try {
                    // noinspection BusyWait
                    Thread.sleep(period);
                } catch (InterruptedException ignored) {
                }
            }
            jedis.close();
        }).start();
    }

    public void close() {
        closed = true;
    }
}
